package orbitPrototype.gui;

import java.awt.event.MouseEvent;
import java.util.ArrayList;

import orbitPrototype.Settings;
import orbitPrototype.objects.DisplayObject;
import orbitPrototype.objects.DisplayObjectContainer;

/**
 * Description: Manages all GUI windows and directs input to appropriate methods. Also handles
 * 				in what order GUI windows are drawn. 
 * 
 */
public class GUIWindowManager extends DisplayObjectContainer
{
	private GUIWindow _draggingActive = null;
	
	private GUISimpleButton _buttonHighlighted = null;
	private GUISimpleButton _buttonPressed = null;
	
	public GUIWindowManager()
	{
		super(Settings.FRAME_WIDTH, Settings.FRAME_HEIGHT);
	}
		
	/*
	 * MOUSE INPUT ETC
	 */
	
	private void setButtonState(GUISimpleButton button, boolean press)
	{
		// It's a pressing matter
		if(press)
		{
			// No previously pressed & have new
			if(_buttonPressed == null && button != null)
			{
				_buttonPressed = button;
				_buttonPressed.downState();
			}
			else if(_buttonPressed != null && button == null)
			{
				_buttonPressed.hoverState();
				_buttonPressed = null;
			}
		}
		// No previously highlighted
		else if(_buttonHighlighted != null)
		{
			if(button != null)
			{
				_buttonHighlighted.defaultState();
				_buttonHighlighted = button;
				_buttonHighlighted.hoverState();
			}
			else
			{
				_buttonHighlighted.defaultState();
				_buttonHighlighted = null;
			}
		}
		// New highlighted
		else if(button != null)
		{
			_buttonHighlighted = button;
			_buttonHighlighted.hoverState();
		}
	}
	
	public void mouseDown(int x, int y, int mButton)
	{
		if(mButton == MouseEvent.BUTTON1)
		{
			setButtonState(getButtonAtCoordinates(x, y), true);
		}
	}
	
	public void mouseUp(int x, int y, int mButton)
	{
		if(mButton == MouseEvent.BUTTON1)
		{
			if(getButtonAtCoordinates(x, y) == _buttonPressed && _buttonPressed != null)
			{
				_buttonPressed.action();
			}
			
			if(_buttonPressed != null)
			{
				setButtonState(null, true);
			}
		}
	}
	
	/**
	 * Description:	Handles highlighting of buttons upon mouse movement over them.
	 * @param x
	 * @param y
	 */
	public void mouseMoved(int x, int y)
	{
		GUISimpleButton button = getButtonAtCoordinates(x, y);
		
		setButtonState(button, false);
	}
	
	public void primaryMouseDrag(int x, int y, boolean start)
	{
		if(start)
		{
			_draggingActive = getWindowDragged(x, y);
		}
		else if(_draggingActive != null)
		{
			this.moveToFront(_draggingActive);
			_draggingActive.setX(_draggingActive.getX() + (x - _draggingActive.getX()));
			_draggingActive.setY(_draggingActive.getY() + (y - _draggingActive.getY()));
			
			//Util.output("Window X: " + _draggingActive.getX());
		}
		
		
	}
	
	public GUIWindow getWindowDragged(int x, int y)
	{
		GUIWindow window = getWindowAtCoordinates(x, y);
		
		if(window != null)
		{
			GUIWindowDragArea dragArea = getDragAreaInWindow(x, y, window);
			
			if(dragArea != null)
			{				
				return window;
			}
		}

		return null;
	}
	
	public GUISimpleButton getButtonAtCoordinates(int x, int y)
	{
		GUIWindow window = getWindowAtCoordinates(x, y);
		
		if(window != null)
		{
			GUISimpleButton button = getButtonAtCoordinatesInWindow(x, y, window);
			
			return button;
		}
		
		return null;
	}
	
	public GUIWindow getWindowAtCoordinates(int x, int y)
	{
		ArrayList<DisplayObject> displayObjectList = this.getDisplayObjectsUnderPoint(x, y);
		
		for(DisplayObject displayObject:displayObjectList)
		{			
			if(displayObject.getClass() == GUIWindow.class)
			{
				return (GUIWindow) displayObject;
			}
		}
		
		return null;
	}
	
	public GUISimpleButton getButtonAtCoordinatesInWindow(int x, int y, GUIWindow window)
	{
		ArrayList<DisplayObject> displayObjectList = window.getDisplayObjectsUnderPoint(x, y);
		
		for(DisplayObject displayObject:displayObjectList)
		{	
			if(GUISimpleButton.class.isAssignableFrom(displayObject.getClass()))
			{
				return (GUISimpleButton) displayObject;
			}
		}
		
		return null;
	}
	
	public GUIWindowDragArea getDragAreaInWindow(int x, int y, GUIWindow window)
	{
		ArrayList<DisplayObject> displayObjectList = window.getDisplayObjectsUnderPoint(x, y);
		
		for(DisplayObject displayObject:displayObjectList)
		{	
			if(displayObject.getClass() == GUIWindowDragArea.class)
			{
				return (GUIWindowDragArea) displayObject;
			}
		}
		
		return null;
	}
		
}
